package site.jlopen.kuscia.rpc.impl;

import java.io.FileNotFoundException;

import org.secretflow.v1alpha1.factory.KusciaAPIChannelFactory;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass.BatchQueryDomainRequest;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass.BatchQueryDomainResponse;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass.CreateDomainRequest;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass.CreateDomainResponse;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass.DeleteDomainRequest;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass.DeleteDomainResponse;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass.QueryDomainRequest;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass.QueryDomainResponse;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass.UpdateDomainRequest;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass.UpdateDomainResponse;
import org.secretflow.v1alpha1.kusciaapi.DomainServiceGrpc;
import org.secretflow.v1alpha1.kusciaapi.DomainServiceGrpc.DomainServiceBlockingStub;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import site.jlopen.kuscia.rpc.KusciaDomainRpc;
import site.jlopen.kuscia.exception.SdkBaseException;
import site.jlopen.kuscia.properties.KusciaAPIProperties;

import io.grpc.ManagedChannel;
import io.grpc.StatusRuntimeException;

public class KusciaDomainRpcImpl implements KusciaDomainRpc {
	private static Logger logger = LoggerFactory.getLogger(KusciaDomainRpcImpl.class);

	private DomainServiceBlockingStub blockingStub;
	private ManagedChannel channel;

	public KusciaDomainRpcImpl(KusciaAPIProperties properties) {
		try {
			KusciaAPIChannelFactory channelFactory = new KusciaAPIChannelFactory(properties.getAddress(),
					properties.getTokenFile(), properties.getTls(), properties.getProtocol());
			this.channel = channelFactory.newClientChannel();
			this.blockingStub = DomainServiceGrpc.newBlockingStub(channel);
		} catch (Exception e) {
			if(e instanceof FileNotFoundException) {
				throw SdkBaseException.of("证书文件不存在", e);
			}
			throw SdkBaseException.of("Channel通讯异常", e);
		}
	}

	@Override
	public CreateDomainResponse createDomain(CreateDomainRequest request) throws Exception{
		try {
			DomainOuterClass.CreateDomainResponse response = blockingStub.createDomain(request);
			checkResponse(response.getStatus());
			return response;
		} catch (Exception e) {
			logger.error("创建节点：{}", e);
		} finally {
			if(null != channel) {
				channel.shutdownNow();
			}
		}
		return null;
	}

	@Override
	public UpdateDomainResponse updateDomain(UpdateDomainRequest request) throws Exception{
		try {
			DomainOuterClass.UpdateDomainResponse response = blockingStub.updateDomain(request);
			checkResponse(response.getStatus());
			return response;
		} catch (Exception e) {
			logger.error("更新节点状态：{}", e);
		} finally {
			if(null != channel) {
				channel.shutdownNow();
			}
		}
		return null;
	}

	@Override
	public DeleteDomainResponse deleteDomain(DeleteDomainRequest request) throws Exception{
		try {
			DomainOuterClass.DeleteDomainResponse response = blockingStub.deleteDomain(request);
			checkResponse(response.getStatus());
			return response;
		} catch (Exception e) {
			logger.error("删除节点：{}", e);
			return null;
		} finally {
			if(null != channel) {
				channel.shutdownNow();
			}
		}
	}

	@Override
	public QueryDomainResponse queryDomain(QueryDomainRequest request) throws Exception {
		try {
			QueryDomainResponse response = blockingStub.queryDomain(request);
			checkResponse(response.getStatus());
			return response;
		} catch (StatusRuntimeException e) {
			logger.error("查询节点异常：{}", e);
			throw e;
		} finally {
			if(null != channel) {
				channel.shutdownNow();
			}
		}
	}

	@Override
	public BatchQueryDomainResponse batchQueryDomain(BatchQueryDomainRequest request) throws Exception{
		try {
			DomainOuterClass.BatchQueryDomainResponse response = blockingStub.batchQueryDomain(request);
			checkResponse(response.getStatus());
			return response;
		} catch (Exception e) {
			logger.error("批量查询节点状态：{}", e);
			return null;
		} finally {
			if(null != channel) {
				channel.shutdownNow();
			}
		}
	}
}